#ifndef ULINUX_UTILS_ASCII_STRING_STRING_H
#define ULINUX_UTILS_ASCII_STRING_STRING_H
//******************************************************************************
//*this code is protected by the GNU affero GPLv3
//*author:Sylvain BERTRAND (sylvain.bertrand AT gmail dot com)
//*                        <digital.ragnarok AT gmail dot com>
//******************************************************************************
//strncmp - Compare two length-limited strings
//@cs: One string
//@ct: Another string
//@n: The maximum number of bytes to compare
static inline ulinux_s8 ulinux_strncmp(void *str_cs,void *str_ct,ulinux_u64 n)
{
  ulinux_u8 *cs=str_cs;
  ulinux_u8 *ct=str_ct;
  ulinux_u8 c1,c2;
  while(n){
    c1=*cs++;
    c2=*ct++;
    if(c1!=c2) return c1<c2?-1:1;
    if(!c1) break;
    n--;
  }
  return 0;
}

//use carefully
static inline ulinux_s8 ulinux_strcmp(void *str_cs,void *str_ct)
{
  ulinux_u8 *cs=str_cs;
  ulinux_u8 *ct=str_ct;
  ulinux_u8 c1,c2;
  while(1){
    c1=*cs++;
    c2=*ct++;
    if(c1!=c2) return c1<c2?-1:1;
    if(!c1) break;
  }
  return 0;
}

static inline void ulinux_strncpy(void *str_d,void *str_s,ulinux_u64 n)
{
  ulinux_u8 *d=str_d;
  ulinux_u8 *s=str_s;

  while(n&&*s){
    *d++=*s++;
    n--;
  }
  while(n){
    *d++=0;
    n--;
  }
}

static inline ulinux_u8 ulinux_strnlen(ulinux_u64 *sz,void *str_start,
                                                                 ulinux_u64 max)
{
  ulinux_u8 *start=str_start;
  ulinux_u8 *end;
  for(end=start;max--&&*end!=0;++end);
  if(*end==0){
    *sz=end-start;
    return 1;
  }
  return 0;
}

//use carefully
static inline ulinux_u64 ulinux_strlen(void *str_start)
{
  ulinux_u8 *start=str_start;
  ulinux_u8 *end;
  for(end=start;*end!=0;++end);
  return end-start;
}

//use carefully
static inline void *ulinux_strcat(void *str_dest,void *str_src)
{
  ulinux_u8 *dest=str_dest;
  ulinux_u8 *src=str_src;
  ulinux_u8 *tmp=dest;

  while(*dest) dest++;
  while((*dest++=*src++)!='\0');
  return tmp;
}
#endif
